package com.dg.service.impl;

import com.dg.dao.AclMapper;
import com.dg.dao.AclModuleMapper;
import com.dg.dto.AclModuleDto;
import com.dg.exception.ParamException;
import com.dg.param.AclModuleParam;
import com.dg.pojo.AclModule;
import com.dg.service.AclModuleService;
import com.dg.util.ValidatorUtil;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class AclModuleServiceImpl implements AclModuleService {

    @Autowired
    private AclModuleMapper aclModuleMapper;
    @Autowired
    private AclMapper aclMapper;

    @Override
    public List<AclModuleDto> list(){
        List<AclModule> list = aclModuleMapper.getAll();
        Multimap<Integer,AclModuleDto> map = ArrayListMultimap.create();
        //获取一级模块
        List<AclModuleDto> rootList = Lists.newArrayList();
        for (AclModule aclModule : list){
            AclModuleDto dto = AclModuleDto.adapter(aclModule);
            if(aclModule.getParentId() == 0){
                rootList.add(dto);
            }
            map.put(aclModule.getParentId(),dto);
        }
        //根据seq排序
        Collections.sort(rootList, aclModuleSeqComparator);

        return aclModuleDtoListToTree(rootList, map);
    }

    /**
     * 使用递归算法组装权限模块树
     * @param rootList
     * @param map
     * @return
     */
    private List<AclModuleDto> aclModuleDtoListToTree(List<AclModuleDto> rootList, Multimap<Integer, AclModuleDto> map) {
        for (AclModuleDto aclModuleDto : rootList){
            List<AclModuleDto> aclModuleList =(List<AclModuleDto>) map.get(aclModuleDto.getId());
            //根据seq排序
            Collections.sort(aclModuleList, aclModuleSeqComparator);
            aclModuleDto.setChildren(aclModuleList);

            aclModuleDtoListToTree(aclModuleList, map);
        }
        return rootList;
    }

    @Override
    public void save(AclModuleParam param) {
        ValidatorUtil.validate(param);
        if(checkExist(param.getId(),param.getParentId(), param.getName())){
            throw new ParamException("当前权限模块已存在此名称");
        }
        AclModule aclModule = AclModule.builder().name(param.getName()).parentId(param.getParentId())
                .status(param.getStatus()).seq(param.getSeq()).remark(param.getRemark())
                .operator("admin").operateIp("127.0.0.1").operateTime(new Date()).build();

        aclModuleMapper.insertSelective(aclModule);
    }

    @Override
    public void update(AclModuleParam param){
        ValidatorUtil.validate(param);
        if(checkExist(param.getId(), param.getParentId(), param.getName())){
            throw new ParamException("当前层级已存在此权限模块名称");
        }
        AclModule aclModule = AclModule.builder().id(param.getId()).name(param.getName()).parentId(param.getParentId())
                .status(param.getStatus()).seq(param.getSeq()).remark(param.getRemark())
                .operator("admin").operateIp("127.0.0.1").operateTime(new Date()).build();
        aclModuleMapper.updateByPrimaryKeySelective(aclModule);
    }

    @Override
    public AclModuleDto getAclModule(Integer id) {
        if(id == null){
            throw new ParamException("id不能为空");
        }
        AclModule aclModule = aclModuleMapper.selectByPrimaryKey(id);
        AclModule parent = aclModuleMapper.selectByPrimaryKey(aclModule.getParentId());
        AclModuleDto aclModuleDto = AclModuleDto.adapter(aclModule, parent);
        return aclModuleDto;
    }

    @Override
    public void saveOrUpdate(AclModuleParam param) {
        ValidatorUtil.validate(param);
        if(checkExist(param.getId(), param.getParentId(), param.getName())){
            throw new ParamException("当前层级已存在此权限模块名称");
        }
        AclModule aclModule = AclModule.builder().id(param.getId()).name(param.getName()).parentId(param.getParentId())
                .status(param.getStatus()).seq(param.getSeq()).remark(param.getRemark())
                .operator("admin").operateIp("127.0.0.1").operateTime(new Date()).build();
        if(aclModule.getId() == null){
            aclModuleMapper.insertSelective(aclModule);
        }else{
            aclModuleMapper.updateByPrimaryKeySelective(aclModule);
        }
    }

    @Override
    public void delete(Integer id) {
        if(id == null){
            throw new ParamException("id不能为空");
        }
        if(checkChildAclModuleExistById(id)){
            throw new ParamException("模块下面有子模块，请先删除子模块");
        }
        if(checkAclExistById(id)){
            throw new ParamException("模块下面有权限点，请先删除权限点");
        }

        aclModuleMapper.deleteByPrimaryKey(id);
    }

    private boolean checkExist(Integer id, Integer parentId, String name) {
        return  aclModuleMapper.findByName(id, parentId, name) > 0;
    }

    private boolean checkChildAclModuleExistById(Integer id) {
        return aclModuleMapper.countByModuleId(id) > 0;
    }

    private boolean checkAclExistById(Integer id) {
        return aclMapper.countByModuleId(id) > 0;
    }

    private Comparator<AclModuleDto> aclModuleSeqComparator = new Comparator<AclModuleDto>() {
        @Override
        public int compare(AclModuleDto o1, AclModuleDto o2) {
            return o1.getSeq() - o2.getSeq();
        }
    };

}
